/* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useEffect, useRef, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { Button, Col, message, Row, Space, Spin } from 'antd';
import { ManListenCallSession } from 'seats/schema/Task';
import { useSelector, useDispatch } from 'react-redux';
import { setSeatRest, setWorkspaceInfo } from 'store/root/action';
import './style.scss';
import { JSONObject } from 'seats/schema/common';
import { CallTaskInfoMsg } from 'seats/schema/SocketMessage';
import {
  modifySeatBusy,
  modifySeatFree,
  modifySeatRest,
  postHeart,
} from 'seats/servers/modules/Task';
import { getSocket } from 'servers/socket';
import UsersInfo from '../HumanIntervention/components/UsersInfo';
import CallSummary from './components/CallSummary';
import CallTime from '../../../components/CallTime';
import { tasksHangup } from '../../../servers/modules/CheckInOut';
import eventBus from 'utils/eventBus';
import { renderExceptionDom } from '../TaskTool';

// 人人呼叫页面
const WorkspaceForPP: React.FC = () => {
  const [pageLoading, setPageLoading] = useState<boolean>(false); // loading状态
  // 是否展示人工操作界面
  const [showHumanPage, setShowHumanPage] = useState(false);
  // 通话是否挂机
  const [inCall, setInCall] = useState(false);
  // 任务类型：暂停、禁呼、结束
  const [taskQuitType, setTaskQuitType] = useState<any>(undefined);
  // 推送的任务信息的sessions，挂断后，立即清空
  const [callSession, setCallSession] = useState<ManListenCallSession>({} as ManListenCallSession);
  // 推送的任务信息，已完成，进行中
  const [callInfo, setCallInfo] = useState<CallTaskInfoMsg>({} as CallTaskInfoMsg);
  const taskInfo = useSelector((state: JSONObject) => state.workspaceInfo); // 该单个任务详情
  const seatRest = useSelector((state: JSONObject) => state.seatRest); // on 开启小休 off 取消小休
  const dispatch = useDispatch(); // react-redux 触发action
  const history = useHistory(); // history 路由信息
  /**心跳计时器*/
  const timer = useRef<any>(undefined);
  /**缓存当前通话callId，操作【返回】后清空 */
  const callSessionRef = useRef<any>(undefined);
  /**计时器执行次数 */
  let count = 0;
  /**自动退出任务执行中 */
  const isAutoQuitRef = useRef<any>(undefined);
  /**
   *操作-小休
   * on 开启小休 off 取消小休
   * 小休中，当前有对话的继续，不再推送新的对话，退出任务，结束示闲
   * 恢复后，继续推送新的对话
   */
  const handleSeatRest = async () => {
    setPageLoading(true);
    const state: 'on' | 'off' = seatRest === 'off' ? 'on' : 'off';
    try {
      await modifySeatRest({
        restSwitch: state,
      });
      message.success('操作成功', 1);
      dispatch(setSeatRest(state));
    } catch (error) {
      if (seatRest === 'on') {
        message.info('恢复失败，请稍后尝试或退出任务', 1);
      }
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
    setPageLoading(false);
  };

  /**清除缓存，回任务列表页面 */
  const goTaskListPage = () => {
    // 恢复示闲工作台配置
    dispatch(setSeatRest('off'));
    dispatch(setWorkspaceInfo({}));
    // 回到任务列表
    history.replace('/webseats/seats/callTask?type=3');
  };

  /**操作-退出任务 */
  const handleQuitTask = async () => {
    const { taskId } = taskInfo;
    if (!taskId) {
      goTaskListPage();
      return;
    }
    setPageLoading(true);
    try {
      // 操作-请求示忙
      await modifySeatBusy(taskId);
      console.log('✅ 操作-退出任务(示忙成功)--close workspace');
      goTaskListPage();
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
    setPageLoading(false);
  };

  /**人人自动退出任务：
   * 条件-非人机交互界面
   * 任务结束，任务暂停--当前通话挂断后推送一次
   * 任务禁呼--每秒推送 */
  const autoQuitTask = (type: string) => {
    if (isAutoQuitRef.current) {
      console.log('正在进行自动退出，不能重复操作。。。。。');
      return;
    }
    const msg: JSONObject = {
      paused: '任务已被管理员暂停',
      forbid: '已到达任务禁呼时间',
      end: '任务已完成',
    };
    const callId = callSessionRef.current;
    // callId为空，代表是工作台界面
    if (!callId) {
      isAutoQuitRef.current = true;
      message.info(msg[type], 1);
      setTimeout(handleQuitTask, 1000);
    }
  };

  /**
   * 请求示闲接口 人人任务
   * 接口使用场景：1.任务列表点击示闲
   * @param {number} taskInfo 任务基本信息
   */
  async function doSeatFreeForPP() {
    const { taskId } = taskInfo;
    try {
      await modifySeatFree(taskId, {});
      console.log('✅ 人人任务页面-操作-示闲成功');
    } catch (error) {
      console.log('人人任务页面-示闲失败');
    }
  }

  /**操作【返回】按钮-恢复示闲工作台配置*/
  const goBack = async () => {
    setShowHumanPage(false);
    // 清除通话callId
    setCallSession({} as ManListenCallSession);
    callSessionRef.current = undefined;
    if (taskQuitType) {
      console.log('任务中止类型', taskQuitType);
      autoQuitTask(taskQuitType);
      return;
    }
    // 场景：继续示闲,执行任务，接入电话
    await doSeatFreeForPP();
  };

  /**
   * 绑定socket事件
   * dialogueContentEvent： 获取单句会话消息，渲染至页面
   * callTaskStatusEvent： 获取当前机器人正在 呼叫/通话 的列表并渲染
   */
  const addSocketEvent = () => {
    const socket = getSocket();
    // 事件-任务状态
    socket.addEvent('callTaskStatusEvent', (data: JSONObject) => {
      console.log('任务推送****callId', callSessionRef.current);
      // 任务Id
      const { taskId } = taskInfo;
      // 查找当前任务id对应的socket信息
      if (data.taskId !== taskId?.toString()) {
        return;
      }
      console.log('人人任务==1==callTaskStatusEvent', data);
      setCallInfo(data as CallTaskInfoMsg);
      if (data.sessions.length > 0) {
        const { callId, callRecordId, number } = data.sessions[0];
        console.log('人人任务==2==callTaskStatusEvent', number, callId, callRecordId);
        const obj: any = {
          callId,
          callRecordId,
          number,
        };
        setCallSession(obj); // 通话信息sessions 只有一个
        callSessionRef.current = callId;
      }
      const type = data.eventType;
      // 任务被暂停、到禁呼时间、任务结束，示闲工作台界面需要自动退出任务
      // socket推送，只推一次，任务结束，任务暂停；任务禁呼一直推送
      if (type === 'paused' || type === 'end' || type === 'forbid') {
        autoQuitTask(type);
        setTaskQuitType(type);
      } else {
        setTaskQuitType(undefined);
      }
    });
  };

  /**
   * 监听sip事件 newRTCSession
   */
  const bindSipEvent = () => {
    // 挂机消息
    eventBus.on('ended', () => {
      console.log('ended**挂断===inCall', inCall);
      // 呼叫用户挂断
      setInCall(false);
    });

    // 通话中
    eventBus.on('confirmed', () => {
      setInCall(true);
      setShowHumanPage(true);
    });
  };

  const removeSipEvent = () => {
    eventBus.remove('ended');
    eventBus.remove('confirmed');
  };
  /**
   * 坐席操作【挂断】
   */
  const stopRing = async () => {
    const { callId } = callSession;
    console.log(`坐席操作【挂断】centerCallId----${callId}`);
    if (!callId) return;
    try {
      const result = await tasksHangup(callId);
      if (result.code === 0) {
        message.success('挂断成功', 1);
        setInCall(false);
      }
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
  };

  /** 卸载socket事件*/
  const removeSocketEvent = () => {
    console.log('示闲工作台->>>>socket事件-删除');
    const socket = getSocket();
    socket.removeEvent(['callTaskStatusEvent', 'dialogueContentEvent']);
  };

  /**发送心跳 */
  async function doHeart() {
    const time = new Date().toLocaleTimeString();
    // console.log('【人人】工作台-心跳******请求发送时间', time);
    try {
      const res = await postHeart();
      const newtime = new Date().toLocaleTimeString();
      // console.log('【人人】工作台-心跳>>>>>>>>返回code码', res.code, '****请求返回时间', newtime);
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
  }

  useEffect(() => {
    /**开启定时器 */
    function startTimer() {
      // console.log('【人人】工作台-work-心跳-次数', count);
      doHeart();
      count++;
      // 递归调用，避免用setInterval，长时间停留误差
      timer.current = setTimeout(() => {
        startTimer();
      }, 1000);
    }

    /**清除定时器 */
    function clearTimer() {
      if (!timer.current) {
        return;
      }
      const time = new Date().toLocaleTimeString();
      // console.log('【人人】工作台-work-心跳****终止', time, timer.current);
      clearTimeout(timer.current);
      timer.current = null;
      // eslint-disable-next-line react-hooks/exhaustive-deps
      count = 0;
    }

    startTimer();
    bindSipEvent();
    addSocketEvent();
    return () => {
      console.log('leave out！！！-----退出>>>>>人人示闲页面');
      clearTimer();
      removeSocketEvent();
      removeSipEvent();
    };
  }, []);

  /**
   * 渲染工作台header顶部按钮
   */
  function renderHeaderButton() {
    if (showHumanPage) {
      // 人工界面展示
      if (inCall) {
        // 接通中
        return (
          callInfo.taskId &&
          callSession.callId && (
            <Space>
              <CallTime beginTime={callSession.inviteTime} />
              <Button type="primary" style={{ marginRight: 8 }} onClick={stopRing}>
                挂断
              </Button>
            </Space>
          )
        );
      } else {
        // 通话挂断
        return (
          <Space>
            <Button type="primary" style={{ marginRight: 8 }} onClick={goBack}>
              返回
            </Button>
            <Button onClick={handleQuitTask}>退出任务</Button>
          </Space>
        );
      }
    } else {
      // 非人工界面
      return (
        <Space>
          <Button onClick={handleSeatRest} type="primary" style={{ marginRight: 8 }}>
            {seatRest === 'on' ? '恢复' : '小休'}
          </Button>
          <Button onClick={handleQuitTask}>退出任务</Button>
        </Space>
      );
    }
  }

  return (
    <div className="common-full-page workspace-pp-page">
      <Spin spinning={pageLoading} size="large" tip="加载中">
        <div className="header">
          <Row>
            <Col flex="auto" className="title">
              <span>当前任务：{taskInfo?.taskName}</span>
              <span>
                任务进度：
                {callInfo?.countComplete || taskInfo.finishedTaskNum} /{taskInfo.totalTaskNum || 0}
              </span>
              <span>当前坐席组：{taskInfo.seatsGroupName}</span>
            </Col>
            <Col>{renderHeaderButton()}</Col>
          </Row>
        </div>
        <div className="body">
          {showHumanPage && callInfo.taskId && callSession.callRecordId ? (
            <Row className="box-row">
              <Col className="box box-wpp" flex="2 2 0">
                <UsersInfo callRecordId={callSession.callRecordId} />
              </Col>
              <Col className="box box-wpp" flex="2 2 0">
                <CallSummary callRecordId={callSession.callRecordId} />
              </Col>
            </Row>
          ) : (
            renderExceptionDom(callInfo, seatRest)
          )}
        </div>
      </Spin>
    </div>
  );
};
export default WorkspaceForPP;
